home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ov143b.zip / OVHELP.C < prev    next >
C/C++ Source or Header  |  1993-01-04  |  11KB  |  347 lines

  1. /*  012  23-May-87  ovhelp.c
  2.  
  3.         Copyright (c) 1986,1987 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <setjmp.h>
  8. #include "ov.h"
  9. #include "overr.h"
  10. #include "menu.h"
  11. #include "direct.h"
  12. #include "strmem.h"
  13.  
  14. #define H_bar (0xcd)
  15.  
  16. #define HLINESIZ 80    /* max size of a help line - coordinate with cvthlp.c */
  17. #define NSELS 20       /* max # menu ents/topic   - coordinate with cvthlp.c */
  18. #define STKSIZ 10      /* depth of prev screen stack */
  19.  
  20. static FILE *hlp;
  21. static char *helpfile = "ov.hlp";
  22. static char *nohelp = " - no help available!";
  23.  
  24. int help_exit(), help_back(), help_sel();
  25.  
  26. extern MENU *top_menu, top_help_menu[];
  27.  
  28. static MENU pmenu =
  29.    { "Prev", "Return to the previous help screen", help_back, top_help_menu };
  30. static MENU qmenu = { "Quit", "Quit help", help_exit, top_help_menu };
  31.  
  32. static int stkidx;
  33. static char *buffer;
  34. static MENU top_help_menu[NSELS];
  35. static unsigned char save_restricted;
  36. static long lastsel, offsets[NSELS], offstack[STKSIZ];
  37.  
  38. extern char *cantopen;
  39. extern MENU_STATE curmenu;
  40. extern jmp_buf back_to_main;
  41. extern unsigned char restricted;
  42. extern unsigned char help_display;
  43.  
  44. FILE *pathopen();
  45. char *strchr(), *getenv(), *hgets();
  46.  
  47.  
  48. /******************************************************************************
  49.                                    H E L P
  50.  *****************************************************************************/
  51.  
  52. help() {               /* provide help on using OverView */
  53.  
  54.    register int ch;
  55.  
  56.    if (help_display)                   /* don't work recurrsively */
  57.       return;
  58.  
  59.    /* help_display gets set here in case there is an error in help_init()
  60.       and the user asks for help again instead of hitting ESC - this keeps
  61.       help from trying to init again. */
  62.  
  63.    help_display = TRUE;                /* yes, help is active */
  64.  
  65.    if (!help_init()) {                 /* locate/open help file */
  66.       help_display = FALSE;            /* exit if can't open help file */
  67.       return;
  68.    }
  69.  
  70.    save_restricted = restricted;       /* save current restricted flag and */
  71.    menu_save();                        /*   menu state before changing them */
  72.  
  73.    restricted = TRUE;                  /* disable cmds we don't want */
  74.    top_menu = top_help_menu;           /* use (tbd) help menu */
  75.  
  76.    savescreen();                       /* save the current display screen */
  77.    savecursor();                       /* save the current cursor state */
  78.    hidecursor();                       /* force the cursor off */
  79.  
  80.    help_on(0L);                        /* provide help with top screen */
  81.  
  82.    disp_status();                      /* don't tell user to hit F1 for help */
  83.  
  84.    menu_init();                        /* initialize help menu */
  85.  
  86.    /* we do our own getchr() and menu selections here because we don't
  87.       know what might have been going on before help was called - if
  88.       we returned to the caller, things might get screwed up */
  89.  
  90.    while (help_display && (ch = getchr()) != EOF_CH) {
  91.  
  92.       switch(ch) {
  93.          case ' ': case 9:             /* advance the menu selection pointer */
  94.             menu_advance();
  95.             break;
  96.  
  97.          case 8:                       /* backup the menu selection pointer */
  98.             menu_backup();
  99.             break;
  100.  
  101.          case RETURN:                  /* CR - do current menu selection */
  102.             menu_do_current();
  103.             break;
  104.  
  105.          case 27:                      /* escape - return to top menu */
  106.             menu_init();               /* reset the menu subsystem */
  107.             break;
  108.  
  109.          default:                      /* see if the 1st letter of selection */
  110.             menu_do_char(ch);          /* do menu selection starting with ch */
  111.             break;
  112.       }
  113.    }
  114.  
  115.    if (help_display)
  116.       help_exit();                     /* in case user ^Z's out */
  117. }
  118.  
  119.  
  120. /****************************************************************************
  121.                             H E L P _ I N I T
  122.  ****************************************************************************/
  123.  
  124. static int
  125. help_init() {          /* initialize the help subsystem */
  126.  
  127.    stkidx = 0;                  /* make sure stack of offsets is empty */
  128.    lastsel = 0;                 /* there was no last help topic selection */
  129.  
  130.    /* try to open the default help file somewhere in the PATH -
  131.       give up if helpfile doesn't open */
  132.  
  133.    if ((hlp = pathopen(helpfile,"rb")) == NULL) {
  134.       show_error(0,0,3,cantopen,helpfile,nohelp);
  135.       return(0);
  136.    }
  137.  
  138.    /* try to allocate a large buffer to access the help file */
  139.  
  140.    if (buffer = (char *) malloc(4096))
  141.       setvbuf(hlp,buffer,_IOFBF,4096);
  142.  
  143.    return(1);                  /* say we worked */
  144. }
  145.  
  146.  
  147. /*****************************************************************************
  148.                              H E L P _ E X I T
  149.  *****************************************************************************/
  150.  
  151. static int
  152. help_exit() {          /* exit from help subsystem */
  153.  
  154.    fclose(hlp);                /* close the help file */
  155.  
  156.    if (buffer)                 /* release buffer if used */
  157.       free(buffer);
  158.  
  159.    menu_restore();                     /* restore prior menu */
  160.    help_display = FALSE;               /* help is signing off for now */
  161.    restricted = save_restricted;       /* restore prior restricted flag */
  162.  
  163.    purge_menu();               /* free strings used by menu */
  164.  
  165.    restorescreen();            /* restore the prior display screen */
  166.    restorecursor();            /* restore the previous cursor state */
  167. }
  168.  
  169.  
  170. /****************************************************************************
  171.                             H E L P _ O N
  172.  ****************************************************************************/
  173.  
  174. static int
  175. help_on(offset)         /* provide help on selected topic */
  176. long offset;
  177. {
  178.    char *title, hline[HLINESIZ+1];
  179.  
  180.    *hline = 'X';                               /* error flag */
  181.  
  182.    if (fseek(hlp,offset,SEEK_SET) == 0)        /* seek to the help frame */
  183.       hgets(hline);                            /* get the header line */
  184.  
  185.    if (*hline != '#') {                        /* header lines start with # */
  186.       show_error(0,0,2,"Error reading help file",nohelp);
  187.       help_exit();
  188.       longjmp(back_to_main,16);        /* should never happen, but... */
  189.    }
  190.  
  191.    /* display the topic title at top of screen */
  192.  
  193.    title = strchr(hline,' ');
  194.  
  195.    center_text(FIRST_HROW-1,title ? title+1 : hline+1);
  196.  
  197.    help_menu(hline,offset == 0);       /* create menu */
  198.  
  199.    help_text(hline);                   /* display text */
  200. }
  201.  
  202.  
  203. /****************************************************************************
  204.                            H E L P _ T E X T
  205.  ****************************************************************************/
  206.  
  207. static int
  208. help_text(buf)         /* display help text */
  209. char *buf;
  210. {
  211.    register int i, ntext;
  212.  
  213.    ntext = fgetc(hlp);                 /* read # text lines */
  214.  
  215.    for (i = 0; i < HELP_ROWS; i++) {
  216.  
  217.       gotorc(i+FIRST_HROW,0);
  218.  
  219.       if (ntext)
  220.          if (hgets(buf)) {
  221.             disp_str(buf);
  222.             ntext--;
  223.          } else
  224.             ntext = 0;
  225.  
  226.       clr_eol();
  227.    }
  228. }
  229.  
  230.  
  231. /****************************************************************************
  232.                            H E L P _ M E N U
  233.  ****************************************************************************/
  234.  
  235. static int
  236. help_menu(buf,top)     /* build a menu_selection structure for selection */
  237. char *buf;
  238. int top;
  239. {
  240.    int i;
  241.    char *bp;
  242.    register MENU *mp;
  243.    register int nmenu;
  244.  
  245.    purge_menu();                       /* clear out last menu */
  246.  
  247.    mp = top_help_menu;
  248.  
  249.    /* process each menu entry in the help file */
  250.  
  251.    for (nmenu = fgetc(hlp), i = 0; nmenu > 0; nmenu--, mp++) {
  252.  
  253.       fread((char *)&offsets[i++],sizeof(long),1,hlp); /* read ent's offset */
  254.  
  255.       hgets(buf);                                      /* read keyword/prompt */
  256.  
  257.       /* build menu selection for this entry */
  258.  
  259.      if (bp = strchr(buf,' ')) {
  260.          mp->choice = Strndup(buf,bp-buf);
  261.          mp->prompt = Strdup(bp+1);
  262.          mp->func = help_sel;
  263.          mp->sub_menu = top_help_menu;
  264.       } else {
  265.         i--;                                   /* shouldn't happen */
  266.         mp--;
  267.       }
  268.    }
  269.  
  270.    /* assign the two constant entries and finish it */
  271.  
  272.    if (!top)                           /* don't include Prev entry if */
  273.       *mp++ = pmenu;                   /*   if this is the top help menu */
  274.    *mp++ = qmenu;
  275.  
  276.    mp->choice = NULL;                  /* terminate menu structure */
  277. }
  278.  
  279.  
  280. /****************************************************************************
  281.                         P U R G E _ M E N U
  282.  ****************************************************************************/
  283.  
  284. static int
  285. purge_menu() {         /* release the strings used by current help menu */
  286.  
  287.    register int i;
  288.    register MENU *mp;
  289.  
  290.    for (i = 0, mp = top_help_menu; i < NSELS; i++, mp++) {
  291.  
  292.       if (mp->choice && mp->choice != pmenu.choice && mp->choice != qmenu.choice) {
  293.          free(mp->choice);
  294.          free(mp->prompt);
  295.       }
  296.  
  297.       mp->choice = NULL;
  298.    }
  299. }
  300.  
  301.  
  302. /*****************************************************************************
  303.                             H E L P _ B A C K
  304.  *****************************************************************************/
  305.  
  306. static int
  307. help_back() {          /* backup to previous help display */
  308.  
  309.    if (stkidx)                 /* anything on stack? */
  310.       help_on(lastsel = offstack[--stkidx]);
  311. }
  312.  
  313.  
  314. /*****************************************************************************
  315.                             H E L P _ S E L
  316.  *****************************************************************************/
  317.  
  318. static int
  319. help_sel() {           /* select a help topic */
  320.  
  321.    /* put last selection on stack */
  322.  
  323.    if (stkidx < STKSIZ)
  324.       offstack[stkidx++] = lastsel;
  325.  
  326.    /* give user help on whatever topic is desired */
  327.  
  328.    help_on(lastsel = offsets[curmenu.current_selection]);
  329. }
  330.  
  331.  
  332. /*****************************************************************************
  333.                               H G E T S
  334.  *****************************************************************************/
  335.  
  336. static char *
  337. hgets(buf)             /* get a line from help file the way we want it */
  338. register char *buf;
  339. {
  340.    if (fgets(buf,HLINESIZ,hlp)) {
  341.       buf[strlen(buf)-1] = '\0';       /* we don't need no stinking \n's */
  342.       return(buf);
  343.    }
  344.  
  345.    return(NULL);                       /* couldn't get a line */
  346. }
  347.